package com.joysuch.wwyt.attendant.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joysuch.wwyt.attendant.bean.AttendantPlanBean;
import com.joysuch.wwyt.attendant.bean.AttendantPlanContentBean;
import com.joysuch.wwyt.attendant.bean.AttendantPlanDetailBean;
import com.joysuch.wwyt.attendant.bean.AttendantPlanReqBean;
import com.joysuch.wwyt.attendant.bean.vo.AttendantStatisticsAreaVo;
import com.joysuch.wwyt.attendant.bean.vo.AttendantStatisticsUserVo;
import com.joysuch.wwyt.attendant.bean.vo.PolygonVo;
import com.joysuch.wwyt.attendant.bean.vo.RailReqVo;
import com.joysuch.wwyt.attendant.entity.AttendantArea;
import com.joysuch.wwyt.attendant.entity.AttendantPlan;
import com.joysuch.wwyt.attendant.entity.AttendantPlanContent;
import com.joysuch.wwyt.attendant.enums.AttendantStateEnum;
import com.joysuch.wwyt.attendant.mapper.AttendantPlanMapper;
import com.joysuch.wwyt.attendant.service.*;
import com.joysuch.wwyt.bp.service.BpJobService;
import com.joysuch.wwyt.core.bean.BpUserBean;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiBusinessException;
import com.joysuch.wwyt.core.exception.ApiCoreException;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BaseUserService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.dzhapi.bean.ApiBpJobBean;
import com.joysuch.wwyt.patrol.entity.bean.LocationBean;
import com.joysuch.wwyt.patrol.entity.bean.LocationPointsBean;
import com.joysuch.wwyt.util.DateUtils;
import com.joysuch.wwyt.workflow.api.service.PersonTrajectoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Time;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author xsx
 * @version 1.0
 * @date 2023/2/15 11:43
 */
@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class AttendantPlanServiceImpl extends ServiceImpl<AttendantPlanMapper, AttendantPlan> implements AttendantPlanService {

    @Autowired
    private AttendantPlanMapper attendantPlanMapper;

    @Autowired
    private AttendantPlanContentService attendantPlanContentService;

    @Autowired
    private AttendantAreaService attendantAreaService;

    @Autowired
    private BpJobService bpJobService;

    @Autowired
    private PersonTrajectoryService personTrajectory;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    private BaseConfigService baseConfigService;

    @Autowired
    private BaseUserService baseUserService;


    @Autowired
    private OpenPlatformService openPlatformService;

    @Autowired
    private ExcelService excelService;

    @Override
    public void saveAttendantPlan(AttendantPlanBean bean) throws ApiBusinessException{
        List<AttendantPlanContentBean> list = bean.getList();
        if (list.isEmpty()) {
            throw new ApiBusinessException(Status.FAILED,"自定义添加，保存时至少有一项");
        }
        AttendantPlan plan = new AttendantPlan();
        BeanUtils.copyProperties(bean,plan);
        plan.setStartTime(getTime(bean.getStartTime()));
        plan.setEndTime(getTime(bean.getEndTime()));
        plan.setCreateTime(new Date());
        plan.setUpdateTime(new Date());
        plan.setCreateBy(Context.getCurrentUserId());
        plan.setState(getState(plan.getAttendantTime(),bean.getStartTime()));
        attendantPlanMapper.insert(plan);
        List<AttendantPlanContent> planContents=new ArrayList<>();
        for (AttendantPlanContentBean contentBean : list) {
            AttendantPlanContent planContent = new AttendantPlanContent();
            BeanUtils.copyProperties(contentBean,planContent);
            planContent.setAttendantPlanId(plan.getId());
            planContent.setCreateTime(new Date());
            planContent.setUpdateTime(new Date());
            planContent.setCreateBy(Context.getCurrentUserId());
            planContents.add(planContent);
        }
        attendantPlanContentService.saveBatch(planContents);
        BaseConfig ipConfig = baseConfigService.findConfig(Context.getCurrentTenantId(), Context.getCurrentOrgCode(), BaseConfigCodes.OPEN_SERVICE_SERVER_URL);

        if (ipConfig != null && StringUtils.isNotBlank(ipConfig.getValue()) && plan.getAreaId() != null) {
            syncArea(plan.getAreaId());
        }
    }

    @Async
    public void syncArea(Long areaId){
        AttendantArea area = attendantAreaService.getById(areaId);
        if (area.getIsSync() == 1) {
            return;
        }
        String coordinates = area.getCoordinates();
        if (StringUtils.isBlank(coordinates)) {
            return;
        }
        LocationBean locationBean = JSONObject.parseObject(coordinates, LocationBean.class);
        RailReqVo vo = new RailReqVo();
        vo.setName(area.getName());
        vo.setFloorNo("Floor" + locationBean.getFloorId());
        vo.setMapType(2);
        List<PolygonVo> list = new ArrayList<>();
        List<LocationPointsBean> points = locationBean.getPoints();
        for (LocationPointsBean point : points) {
            PolygonVo polygonVo = new PolygonVo();
            polygonVo.setLatitude(point.getY());
            polygonVo.setLongitude(point.getX());
            list.add(polygonVo);
        }
        vo.setPolygon(list);
        if (StringUtils.isNotBlank(area.getPlatformAreaId())) {
            vo.setUuid(area.getPlatformAreaId());
        }
        try {
                String platformAreaId = openPlatformService.syncArea(vo);
                area.setPlatformAreaId(platformAreaId);
                area.setIsSync(1);
                attendantAreaService.updateById(area);
        } catch (ApiCoreException e) {
            e.printStackTrace();
            log.error("获取开放平台token报错");
        }
    }


    @Override
    public void updateAttendantPlan(AttendantPlanBean bean) throws ApiBusinessException{
        List<AttendantPlanContentBean> list = bean.getList();
        if (list.isEmpty()) {
            throw new ApiBusinessException(Status.FAILED,"自定义添加，保存时至少有一项");
        }
        AttendantPlan oldPlan = attendantPlanMapper.selectById(bean.getId());
        if (oldPlan.getState()!=1){
            throw new ApiBusinessException(Status.FAILED,"任务状态已改变不能修改");
        }
        AttendantPlan plan = new AttendantPlan();
        BeanUtils.copyProperties(bean,plan);
        plan.setStartTime(getTime(bean.getStartTime()));
        plan.setEndTime(getTime(bean.getEndTime()));
        plan.setUpdateTime(new Date());
        plan.setUpdateBy(Context.getCurrentUserId());
        attendantPlanMapper.updateById(plan);
        List<AttendantPlanContent> planContents=new ArrayList<>();
        List<Long> oldIds = attendantPlanContentService.selectIdsByPlanId(bean.getId());
        for (AttendantPlanContentBean contentBean : list) {
            if (contentBean.getId()!=null){
                oldIds.contains(contentBean.getId());
                oldIds.remove(contentBean.getId());
            }
            AttendantPlanContent planContent = new AttendantPlanContent();
            BeanUtils.copyProperties(contentBean,planContent);
            planContent.setAttendantPlanId(plan.getId());
            planContent.setUpdateTime(new Date());
            planContent.setUpdateBy(Context.getCurrentUserId());
            planContents.add(planContent);
        }
        attendantPlanContentService.saveOrUpdateBatch(planContents);
        if (!oldIds.isEmpty()) {
            attendantPlanContentService.removeByIds(oldIds);
        }

    }

    @Override
    public AttendantPlanBean findAttendantPlanBean(Long id) {
        AttendantPlanBean bean = new AttendantPlanBean();
        AttendantPlan plan = attendantPlanMapper.selectById(id);
        BeanUtils.copyProperties(plan,bean);
        List<AttendantPlanContentBean> beans = attendantPlanContentService.selectBeanByPlanId(id);
        AttendantArea area = attendantAreaService.getById(plan.getAreaId());
        if (area!=null) {
            bean.setAreaName(area.getName());
        }
        BpUserBean bpUserBean = baseUserService.selectByUserId(plan.getUserId());
        if (bpUserBean!=null) {
            bean.setUserName(bpUserBean.getRealName());
        }
        Integer start = Integer.parseInt(plan.getStartTime().toString().replaceAll(":","").substring(0,4));
        Integer end = Integer.parseInt(plan.getEndTime().toString().replaceAll(":","").substring(0,4));
        bean.setStartTime(plan.getStartTime().toString().substring(0,5));
        bean.setEndTime(plan.getEndTime().toString().substring(0,5));
        if (start > end) {
            bean.setEndTime(bean.getEndTime() + "(次日)");
        }
        bean.setList(beans);
        return bean;
    }

    @Override
    public Page<AttendantPlanDetailBean> selectPage(AttendantPlanReqBean bean) {
        Page<AttendantPlanDetailBean> page = new Page<>(bean.getPage() + 1, bean.getSize());
        if (bean.getWay() != null && !bean.getWay().equals(5)) {
            Map<String, Date> map = DateUtils.getTime(bean.getWay());
            bean.setStartTime(map.get("startTime"));
            bean.setEndTime(map.get("endTime"));
        }
        if (bean.getWay() != null && bean.getWay().equals(1)){
            bean.setYesterday(DateUtils.getYesterday());
        }
        Page<AttendantPlanDetailBean> beanPage = attendantPlanMapper.selectPlanPage(page, bean);
        if (!beanPage.getRecords().isEmpty()&&!beanPage.getRecords().isEmpty()) {
            List<Long> areaIds = beanPage.getRecords().stream().map(AttendantPlanDetailBean::getAreaId).distinct().collect(Collectors.toList());
            List<Long> jobIds = beanPage.getRecords().stream().map(AttendantPlanDetailBean::getJob).distinct().collect(Collectors.toList());
            List<AttendantArea> areaList = attendantAreaService.selectByIds(areaIds);
            List<ApiBpJobBean> jobBeans = bpJobService.findByIds(jobIds);
            Map<Long, String> areaMap = areaList.stream().collect(Collectors.toMap(AttendantArea::getId, e -> e.getName()));
            Map<Long, String> jobBeanMap = jobBeans.stream().collect(Collectors.toMap(ApiBpJobBean::getId, e -> e.getName()));
            for (AttendantPlanDetailBean record : beanPage.getRecords()) {
                record.setAreaName(areaMap.get(record.getAreaId()));
                record.setJobName(jobBeanMap.get(record.getJob()));
                if (record.getState()!=null) {
                    record.setStateName(AttendantStateEnum.find(record.getState()).getDesc());
                    if (record.getState()==0){
                        record.setStateName("进行中");
                    }
                }
                Integer start = Integer.parseInt(record.getStartTime().replaceAll(":","").substring(0,4));
                Integer end = Integer.parseInt(record.getEndTime().replaceAll(":","").substring(0,4));
                record.setStartTime(record.getStartTime().substring(0,5));
                record.setEndTime(record.getEndTime().substring(0,5));
                if (start > end) {
                    record.setEndTime(record.getEndTime() + "(次日)");
                }
            }
        }
        beanPage.setTotal(page.getTotal());
        return beanPage;
    }

    @Override
    public void delete(Long id) {
        AttendantPlan plan = baseMapper.selectById(id);
        if (plan != null) {
            plan.setDeleteFlag("1");
            baseMapper.updateById(plan);
        }
    }

    @Override
    public void deleteByIds(List<Long> ids) {
        for (Long id : ids) {
            AttendantPlan plan = baseMapper.selectById(id);
            if (plan != null) {
                plan.setDeleteFlag("1");
                baseMapper.updateById(plan);
            }
        }
    }

    @Override
    public long countByStatus(Integer state) {
        return baseMapper.countByStatus(state);
    }

    @Override
    public Page<AttendantStatisticsUserVo> findStatisticsUserPage(Page<AttendantStatisticsUserVo> page, List<Long> userIds,Long jobId, Integer way, Date startTime, Date endTime, String companyCode, Long tenantId) {
        if (way != null && !way.equals(5)) {
            Map<String, Date> map = DateUtils.getTime(way);
            startTime = map.get("startTime");
            endTime = map.get("endTime");
        }
        return baseMapper.findStatisticsUserPage(page,userIds,jobId,way,startTime,endTime,companyCode,tenantId);
    }

    @Override
    public Page<AttendantStatisticsAreaVo> findStatisticsAreaPage(Page<AttendantStatisticsAreaVo> page, List<Long> areaIds, Integer way, Date startTime, Date endTime, String companyCode, Long tenantId) {
        if (way != null && !way.equals(5)) {
            Map<String, Date> map = DateUtils.getTime(way);
            startTime = map.get("startTime");
            endTime = map.get("endTime");
        }
        return baseMapper.findStatisticsAreaPage(page,areaIds,way,startTime,endTime,companyCode,tenantId);
    }

    @Override
    public List<AttendantPlan> selectByTime(Date date,Integer state,Integer way) {
        return baseMapper.selectByTime(date,state,way);
    }

    @Override
    @Transactional
    public List<String> importExcelData(Integer way, MultipartFile file)  {
        List<String> messages = new ArrayList<>();
        XSSFWorkbook workbook = null;
        try {
            workbook = new XSSFWorkbook(file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
            return messages;
        }
        if (workbook != null) {
            try {
                this.getSheetData(workbook.getSheetAt(0), messages,way);
            } catch (Exception e) {
                e.printStackTrace();
                return messages;
            }
        }
        return messages;
    }

    @Override
    public ResultBean export(String idsStr, HttpServletResponse response) {
        List<Long> ids = new ArrayList<>();
        if (StringUtils.isBlank(idsStr)) {
            return ResultBean.fail(500, "请先选择数据");
        }
        String[] split = idsStr.split(",");
        for (String s : split) {
            ids.add(Long.parseLong(s));
        }
        List<AttendantPlanDetailBean> list = baseMapper.selectByIds(ids);
        List<AttendantPlanContentBean> beans = attendantPlanContentService.selectBeanByPlanIds(ids);

        List<Long> areaIds = list.stream().map(AttendantPlanDetailBean::getAreaId).distinct().collect(Collectors.toList());
        Map<Long, String> areaMap=new HashMap<>();
        if (CollectionUtils.isNotEmpty(areaIds)) {
            List<AttendantArea> areaList = attendantAreaService.selectByIds(areaIds);
            areaMap = areaList.stream().collect(Collectors.toMap(AttendantArea::getId, e -> e.getName()));
        }


        Map<Long, List<AttendantPlanContentBean>> map = new HashMap<>();
        for (AttendantPlanContentBean bean : beans) {
            if (map.get(bean.getAttendantPlanId()) != null) {
                List<AttendantPlanContentBean> beanList = map.get(bean.getAttendantPlanId());
                beanList.add(bean);
            } else {
                List<AttendantPlanContentBean> beanList = new ArrayList<>();
                beanList.add(bean);
                map.put(bean.getAttendantPlanId(), beanList);
            }
        }
        List<Map<String, String>> maps = new ArrayList<>();
        List<String> fieldNames = new ArrayList<>();
        List<String> colsName = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (AttendantPlanDetailBean bean : list) {
            LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
            linkedHashMap.put("编号id", bean.getId() + "");
            linkedHashMap.put("跟班计划名称", bean.getName());
            linkedHashMap.put("跟班人员", bean.getUserName());
            linkedHashMap.put("跟班车间/工段", areaMap.get(bean.getAreaId()));
            linkedHashMap.put("跟班日期", sdf.format(bean.getAttendantTime()));
            linkedHashMap.put("开始时间", bean.getStartTime().substring(0,5));
            linkedHashMap.put("结束时间", bean.getEndTime().substring(0,5));
            String signInMethod="定位签到";
            if (bean.getSignInMethod()==0) {
                signInMethod="无需签到";
            }
            linkedHashMap.put("签到方式", signInMethod);
            List<AttendantPlanContentBean> beanList = map.get(bean.getId());
            if (CollectionUtils.isNotEmpty(beanList)) {
                for (int i = 0; i <= beanList.size() - 1; i++) {
                    linkedHashMap.put("跟班检查项目" + i, beanList.get(i).getName());
                }
            }
            maps.add(linkedHashMap);
            Collection<String> values = linkedHashMap.values();
            colsName.addAll(values);
            if (fieldNames.isEmpty()){
                Set<String> keySet = maps.get(0).keySet();
                List<String> keyList = new ArrayList<String>();
                keyList.addAll(keySet);
                fieldNames.addAll(keyList);
            }

        }

        try {
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmm");
            String fileName="跟班计划数据导出"+sdf2.format(new Date());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition","attachment;filename=" + new String(fileName.getBytes("GBK"), "iso8859-1") + ".xlsx");
            excelService.writeToExcel(maps, fieldNames, response.getOutputStream(), fieldNames);
            return ResultBean.success("");
        } catch (IOException e) {
            e.printStackTrace();
            return ResultBean.fail(500, "导出失败");
        }
    }

    private List<String> getSheetData(XSSFSheet sheet, List<String> messages,Integer way)  {
        Integer idIndex = 0;
        Integer nameIndex = 1;
        String name = "";
        Integer userNameIndex = 2;
        Long userId = 0L;
        Integer areaIndex = 3;
        Long areaId = 0L;
        Integer attendantIndex = 4;
        Integer attendantStartIndex = 5;
        Integer attendantEndIndex = 6;
        Date attendantTime;
        Time attendantStartTime;
        String attendantStartTimeStr="";
        Time attendantEndTime;
        Integer signIndex = 7;
        Integer start = 1;
        Integer sign = 0;
        Long id=null;
        if (way == 2) {
            baseMapper.deletePlan();
        }
//        if (way == 3) {
//            start = 0;
//        }
        BaseConfig ipConfig = baseConfigService.findConfig(Context.getCurrentTenantId(), Context.getCurrentOrgCode(), BaseConfigCodes.OPEN_SERVICE_SERVER_URL);
        int ignoreCount = 0;
        int failCount = 0;
        for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
            Boolean t=true;
            XSSFRow row = sheet.getRow(i);
            for (int j = start; j <= 8; j++) {
                if (row.getCell(j) == null||StringUtils.isBlank(row.getCell(j).toString())) {
                  String fieldName="";
                    switch (j){
                        case 1:
                            fieldName="跟班计划名称";
                            break;
                            case 2:
                            fieldName="跟班人员";
                            break;
                            case 3:
                            fieldName="跟班车间/工段";
                            break;
                            case 4:
                            fieldName="跟班日期";
                            break;
                            case 5:
                            fieldName="开始时间";
                            break;
                            case 6:
                            fieldName="结束时间";
                            break;
                            case 7:
                            fieldName="签到方式";
                            break;
                            case 8:
                            fieldName="跟班检查项目";
                            break;
                    }
                    messages.add("第" + (i + 1) + "行," + fieldName + "内容为空");
                    failCount++;
                    t=false;
                    break;
                }
            }
            if (!t){
                continue;
            }
            AttendantPlan plan = new AttendantPlan();
            if (way == 1 && row.getCell(idIndex) != null) {
                String idStr = getCellStringValue(row.getCell(idIndex));
                if (isNumber(idStr)) {
                    id=Long.parseLong(idStr);
                    AttendantPlan attendantPlan = baseMapper.selectById(Integer.parseInt(idStr));
                    if (attendantPlan != null) {
                        messages.add("第" + (i + 1) + "行,已忽略" );
                        ignoreCount++;
                        continue;
                    }
                }
            }
            if ((way == 3 && row.getCell(idIndex) == null)||(way == 3 && StringUtils.isBlank(row.getCell(idIndex).toString()))){
                continue;
            }
            if (way == 3 && row.getCell(idIndex) != null) {
                String idStr = getCellStringValue(row.getCell(idIndex));
                if (isNumber(idStr)) {
                    id=Long.parseLong(idStr);
                    AttendantPlan attendantPlan = baseMapper.selectById(Integer.parseInt(idStr));
                    if (attendantPlan == null) {
                        continue;
                    }
                    if (attendantPlan.getDeleteFlag().equals("1") || !attendantPlan.getState().equals(AttendantStateEnum.NOT_STARTED.getValue())) {
                        messages.add("第" + (i + 1) + "行," + attendantPlan.getName() + "计划正在执行或已完成，不允许修改");
                        failCount++;
                        continue;
                    }
                    plan.setId(attendantPlan.getId());
                }
            }
            if (row.getCell(nameIndex) != null) {
                name = this.getCellStringValue(row.getCell(nameIndex));
                if (name.length() > 64) {
                    messages.add("第" + (i + 1) + "行," + name + "超过限制最多64字");
                    failCount++;
                    continue;
                }
            }
            if (row.getCell(userNameIndex) != null) {
                row.getCell(userNameIndex).setCellType(CellType.STRING);
                String userName = this.getCellStringValue(row.getCell(userNameIndex));
                try {
                    Long num = baseUserService.countNumByName(userName);
                    if (num>1){
                        messages.add("第" + (i + 1) + "行," + userName + "人员重复");
                        failCount++;
                        continue;
                    }
                    userId = baseUserService.selectUserIdByName(userName);
                    if (userId==null){
                        messages.add("第" + (i + 1) + "行,跟班人员不存在 ");
                        failCount++;
                        continue;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    messages.add("第" + (i + 1) + "行," + userName + "人员重复");
                    failCount++;
                    continue;
                }
            }
            if (row.getCell(areaIndex) != null) {
                row.getCell(areaIndex).setCellType(CellType.STRING);
                String areaName = this.getCellStringValue(row.getCell(areaIndex));
                areaId = attendantAreaService.selectIdByName(areaName);
                if (areaId == null) {
                    messages.add("第" + (i + 1) + "行,跟班车间/工段 不存在，请先维护");
                    failCount++;
                    continue;
                }
            }
            if (row.getCell(attendantIndex) != null && row.getCell(attendantStartIndex) != null && row.getCell(attendantEndIndex) != null) {
                try {
                    attendantTime = (row.getCell(attendantIndex).getDateCellValue());
                    attendantStartTimeStr = this.getCellStringValue(row.getCell(attendantStartIndex));
                    String attendantEndTimeStr = this.getCellStringValue(row.getCell(attendantEndIndex));
                    Integer attendantEndTimeNum = Integer.parseInt(attendantEndTimeStr.replaceAll("点", ""));
                    Integer attendantStartTimeNum = Integer.parseInt(attendantStartTimeStr.replaceAll("点", ""));
                    if (attendantEndTimeNum>24||attendantStartTimeNum>24){
                        messages.add("第" + (i + 1) + "行," + "跟班执行时间填写有误");
                        failCount++;
                        continue;
                    }
                    attendantStartTimeStr = attendantStartTimeStr.replaceAll("点", ":00");
                    attendantEndTimeStr = attendantEndTimeStr.replaceAll("点", ":00");
                    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
                    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
                    SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                    String attendantTimeStr = sdf2.format(attendantTime);
                    String time = attendantTimeStr +" "+ attendantStartTimeStr;
                    if (sdf3.parse(time).before(new Date())) {
                        messages.add("第" + (i + 1) + "行," + "跟班执行时间不能填写过去时间");
                        failCount++;
                        continue;
                    }
                    attendantStartTime = new Time(sdf.parse(attendantStartTimeStr).getTime());
                    attendantEndTime = new Time(sdf.parse(attendantEndTimeStr).getTime());
                    plan.setAttendantTime(attendantTime);
                    plan.setStartTime(attendantStartTime);
                    plan.setEndTime(attendantEndTime);
                } catch (Exception e) {
                    e.printStackTrace();
                    messages.add("第" + (i + 1) + "行,跟班日期格式有问题,请输入正确的日期格式(如 2023-02-27)");
                    failCount++;
                    continue;
                }
            }
            if (row.getCell(signIndex) != null) {
                String signName = this.getCellStringValue(row.getCell(signIndex));
                if (signName.equals("定位签到")) {
                    sign = 1;
                }
            }
            if (id!=null){
                plan.setId(id);
            }
            plan.setName(name);
            plan.setUserId(userId);
            plan.setAreaId(areaId);
            plan.setSignInMethod(sign);
            plan.setCreateTime(new Date());
            plan.setCreateBy(Context.getCurrentUserId());
            plan.setState(getState(plan.getAttendantTime(),attendantStartTimeStr));
            if (way == 3) {
                baseMapper.updateById(plan);
            } else {
                baseMapper.insert(plan);
            }
            List<AttendantPlanContent> contents = new ArrayList<>();
            if (way==3){
                attendantPlanContentService.deleteByPlanId(plan.getId());
            }
            for (int j = signIndex+1; j < row.getLastCellNum(); j++) {
                AttendantPlanContent content = new AttendantPlanContent();
                String contentName = this.getCellStringValue(row.getCell(j));
                if (contentName.length() > 64) {
                    messages.add("第" + (i + 1) + "行," + contentName + "超过限制最多64字");
                    failCount++;
                    break;
                }
                content.setName(contentName);
                content.setAttendantPlanId(plan.getId());
                contents.add(content);
            }

            attendantPlanContentService.saveBatch(contents);

            if (ipConfig != null && StringUtils.isNotBlank(ipConfig.getValue()) && plan.getAreaId() != null) {
                syncArea(plan.getAreaId());
            }
        }
        messages.add("共" + sheet.getLastRowNum()  + "条数据");
        messages.add("导入成功" + (sheet.getLastRowNum()  - failCount - ignoreCount)+ "条");
        messages.add("失败" + failCount + "条");
        messages.add("忽略" + ignoreCount + "条");
        return messages;
    }


    /**
     * 如果正则匹配通过 m.matches() 方法返回 true ，反之 false
     * @param str
     * @return
     */
    public static Boolean isNumber(String str) {
        if (StringUtils.isBlank(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[0-9]*$");
        Matcher m = pattern.matcher(str);
        return m.matches();
    }


    public static Time getTime(String timeStr){
        SimpleDateFormat f = new SimpleDateFormat("HH:mm");
        long time = 0;
        try {
            time = f.parse(timeStr).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Time(time);
    }


    public Integer getState(Date attendAntTime, String startTime) {
        Integer state = 1;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String time = sdf.format(attendAntTime);
        String beginTime = time +" "+ startTime;
        try {
            if (sdf2.parse(beginTime).before(new Date())) {
                state = 2;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return state;
    }
    public String getCellStringValue(XSSFCell cell) {
        Object obj = getCellValue(cell, true);
        return obj == null ? null : obj.toString().trim();
    }

    private Object getCellValue(XSSFCell cell, boolean isText) {
        CellType cellType = cell.getCellType();
        DecimalFormat df = new DecimalFormat("0");


        Object value = null;
        switch (cellType) {
            case STRING: {
                value = cell.getStringCellValue();
                break;
            }
            case NUMERIC: {
                value = cell.getNumericCellValue();
                if (isText) {
                    BigDecimal decimal = new BigDecimal(value.toString());
                    int scale = decimal.scale();
                    if (scale < 1) {
                        //小于1代表科学计数或者整数
                        value = df.format(decimal);
                    } else {
                        value = String.valueOf(decimal);
                    }
                    return String.valueOf(value);
                }
                break;
            }
            case FORMULA: {
                value = cell.getNumericCellValue();
                if (isText) {
                    return value.toString();
                }
                break;
            }
        }
        return value;
    }

}
